local BaseData = require("data.base.BaseData")
local UserBaseData = class("UserBaseData", BaseData)
local SkillUnitData = require("data.SkillUnitData")

local schema = {}
schema["name"] = {"string", "我是主角"}
schema["id"] = {"number", 0}
schema["level"] = {"number", 0}
schema["base_id"] = {"number", 0}
schema["skills"] = {"table", {}}
schema["equipments"] = {"table", {}}
schema["jades"] = {"table", {}}
UserBaseData.schema = schema

function UserBaseData:ctor()
    UserBaseData.super.ctor(self)
    self:_initSkills()
    self:_initEquipments()
    self:_initJades()
    self._otherPlayerNames = {}
    self._signalId = G_NetWorkManager:beginCache()
    G_NetWorkManager:add(MessageIDConst.ID_S2C_Login, handler(self, self._s2cLogin))
    G_NetWorkManager:add(MessageIDConst.ID_S2C_Register_User, handler(self, self._s2cRegisterUser))
    G_NetWorkManager:add(MessageIDConst.ID_S2C_UpdatePos, handler(self, self._s2cUpdatePos))
    G_NetWorkManager:add(MessageIDConst.ID_S2C_UpdateVelocity, handler(self, self._s2cUpdateVelocity))
    G_NetWorkManager:add(MessageIDConst.ID_S2C_PlayerLeaveView, handler(self, self._s2cPlayerLeaveView))
    G_NetWorkManager:add(MessageIDConst.ID_S2C_EnterScane, handler(self, self._s2cEnterScane))
    G_NetWorkManager:add(MessageIDConst.ID_S2C_NotifyName, handler(self, self._s2cNotifyName))
    G_NetWorkManager:add(MessageIDConst.ID_S2C_CheckNearPlayers, handler(self, self._s2cCheckNearPlayers))
    G_NetWorkManager:endCache()
end

function UserBaseData:clear()
    G_NetWorkManager:removeCache(self._signalId)
end

function UserBaseData:_initSkills()
    local result = {}
    for i = 1, 4 do
        local skill = SkillUnitData.new()
        skill:update(i)
        table.insert(result, skill)
    end
    self:setSkills(result)
end

function UserBaseData:_initEquipments()
    local StoreConst = require("const.StoreConst")
    local equips = G_StoreManager:getDataList(StoreConst.BATTLE_EQUIP)
    self:setEquipments(equips)
end

function UserBaseData:_initJades()
    local StoreConst = require("const.StoreConst")
    local jades = G_StoreManager:getDataList(StoreConst.BATTLE_JADE)
    self:setJades(jades)
end

function UserBaseData:getOtherPlayerName(userId)
    return self._otherPlayerNames[userId] or ""
end

function UserBaseData:c2sLogin()
    local name = self:getName()
    G_NetWorkManager:send(MessageIDConst.ID_C2S_Login, {userName = name})
end

function UserBaseData:c2sRegister(name, psw)
    G_NetWorkManager:send(MessageIDConst.ID_C2S_Register_User, {usrName = name, usrPsw = psw})
end

function UserBaseData:c2sUpdatePos(sceneId, pos, forward)
    local sPos = {
        x = pos.x,
        y = pos.y,
        z = pos.z
    }
    local sFor = {
        x = forward.x,
        y = forward.y,
        z = forward.z
    }
    G_NetWorkManager:send(
        MessageIDConst.ID_C2S_UpdatePos,
        {
            sceneId = sceneId,
            forward = sFor,
            pos = sPos
        }
    )
end

function UserBaseData:c2sUpdateVelocity(sceneId, pos, forward, vec)
    local sPos = {
        x = pos.x,
        y = pos.y,
        z = pos.z
    }
    local sFor = {
        x = forward.x,
        y = forward.y,
        z = forward.z
    }
    local sVelocity = {
        x = vec.x,
        y = vec.y,
        z = vec.z
    }
    G_NetWorkManager:send(
        MessageIDConst.ID_C2S_UpdateVelocity,
        {
            sceneId = sceneId,
            pos = sPos,
            forward = sFor,
            velocity = sVelocity
        }
    )
end

function UserBaseData:_initScene(sceneId)
    local MAX_MONSTER = 7
    local monstersCfg = require("config.scene_monster").get(sceneId)
    for i = 1, MAX_MONSTER do
        local monsterId = monstersCfg["monster_" .. i]
        if monsterId > 0 then
            local posStr = monstersCfg["reborn_pos_" .. i]
            local posArr = string.split(posStr, "|")
            local pos = {x = tonumber(posArr[1]), y = tonumber(posArr[2]), z = tonumber(posArr[3])}
            G_SignalManager:dispatch(SignalConst.EVENT_SCENE_NOTIFY_MONSTER, sceneId, monsterId, pos, false)
        end
    end
end

function UserBaseData:c2sEnterScane(sceneId, pos, forward)
    if not G_SocketManager:isContenting() then
        self:_initScene(sceneId)
        return
    end
    local sPos = {
        x = pos.x,
        y = pos.y,
        z = pos.z
    }
    local sFor = {
        x = forward.x,
        y = forward.y,
        z = forward.z
    }
    G_NetWorkManager:send(MessageIDConst.ID_C2S_EnterScane, {sceneId = sceneId, pos = sPos, forward = sFor})
end

function UserBaseData:c2sCheckNearPlayers(sceneId)
    G_NetWorkManager:send(MessageIDConst.ID_C2S_CheckNearPlayers, {sceneId = sceneId})
end

function UserBaseData:_onFlush()
    G_UserData:getTeamGroup():clearTeam()
end

function UserBaseData:_s2cLogin(id, message)
    if message.ret ~= 1 then
        return
    end
    local id = rawget(message, "userId")
    self:setId(id)
    self:_onFlush()
    G_SignalManager:dispatch(SignalConst.EVENT_USER_FLUSH_DATA)
end

function UserBaseData:_s2cRegisterUser(id, message)
    if message.ret ~= 1 then
        return
    end
    local usrName = rawget(message, "usrName")
    local usrPsw = rawget(message, "usrPsw")
    G_SignalManager:dispatch(SignalConst.EVENT_USER_REGISTER_SUCCESS)
end

function UserBaseData:_s2cUpdatePos(id, message)
    if message.ret ~= 1 then
        return
    end
    local sceneId = rawget(message, "sceneId")
    local userId = rawget(message, "userId")
    local forward = rawget(message, "forward")
    local pos = rawget(message, "pos")
    G_SignalManager:dispatch(SignalConst.EVENT_OTHER_PLAYER_UPDATE_POS, sceneId, userId, pos, forward)
end

function UserBaseData:_s2cUpdateVelocity(id, message)
    if message.ret ~= 1 then
        return
    end
    local sceneId = rawget(message, "sceneId")
    local userId = rawget(message, "userId")
    local forward = rawget(message, "forward")
    local pos = rawget(message, "pos")
    local velocity = rawget(message, "velocity")
    G_SignalManager:dispatch(SignalConst.EVENT_OTHER_PLAYER_UPDATE_VEC, sceneId, userId, pos, forward, velocity)
end

function UserBaseData:_s2cEnterScane(id, message)
    if message.ret ~= 1 then
        return
    end
    local sceneId = rawget(message, "sceneId")
    local userId = rawget(message, "userId")
    G_SignalManager:dispatch(SignalConst.EVENT_PLAYER_ENTER_SCENE, sceneId, userId)
end

function UserBaseData:_s2cPlayerLeaveView(id, message)
    local userId = rawget(message, "userId")
    printDebug("UserBaseData:_s2cPlayerLeaveView " .. userId)
    G_SignalManager:dispatch(SignalConst.EVENT_PLAYER_LEAVE_VIEW, userId)
end

function UserBaseData:_s2cNotifyName(id, message)
    local userId = rawget(message, "userId")
    local userName = rawget(message, "userName")
    self._otherPlayerNames[userId] = userName
end

function UserBaseData:_s2cCheckNearPlayers(id, message)
    local sceneId = rawget(message, "sceneId")
    local users = rawget(message, "users") or {}
    G_SignalManager:dispatch(SignalConst.EVENT_NEAR_PLAYERS, sceneId, users)
end

return UserBaseData
